<?php
namespace App\Libs\Helper;
use App\Libs\Remote\Remote;


class WeixinGzhHelper{
	//public static $appID = 'wx8ee7f6d66df90804';
	public static $appID = 'wx2685e590bd08501b';
	//public static $appsecret = 'ddd51029595cf859394a28047bca36f1';
	public static $appsecret = '274c3659c2f53c03c4cf440cf9082d56';
	public static $key = '9xjEFkpVBswJ74bL5isfjHdQSjz9QoZV';
	private static $prefix = 'weixin:';
	public static $mchID = '1488937032';

	/**
	 *  @Usage : 通过access_token和openid页面授权用户信息
	 *	return array
	 */
	public static function getUserinfo($code){
		
		$return = self::getOpenidbycode($code);
		//$userinfo = self::http_get_data('https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$return['access_token'].'&openid='.$return['openid'].'&lang=zh_CN ');
		$userinfo = self::http_get_data('https://api.weixin.qq.com/sns/userinfo?access_token='.$return['access_token'].'&openid='.$return['openid'].'&lang=zh_CN ');
		if(!empty($userinfo['errcode'])){
			//此时应该写日志，暂未写
			return false;
		}else{
			return $userinfo;
		}
	}

	/**
	 *  @Usage : 通过code获取用户accsee_token 和openid
	 *	return array
	 */
	public static function getOpenidbycode($code){
		$returns = self::http_get_data('https://api.weixin.qq.com/sns/oauth2/access_token?appid='.self::$appID.'&secret='.self::$appsecret.'&code='.$code.'&grant_type=authorization_code');
		if(!empty($returns['errcode'])){
			//此时应该写日志，暂未写
			return false;
		}else{
			return $returns;
		}
	}

	/**
	*	@Usage ： 获取weChat TOKEN
	*	return string
	*/
	public static function token(){
		$key = self::generate("wx_token");
		$tokenMem = \App\Libs\Cache\Memcached::get(self::$prefix . $key);
		if(!empty($tokenMem)){
			return $tokenMem;
		}
		/*if (isset($_COOKIE['TOKEN_KEY']) && ! empty($_COOKIE['TOKEN_KEY'])) {
            return trim($_COOKIE['TOKEN_KEY']);
        }*/
		$returns = self::http_get_data('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.self::$appID.'&secret='.self::$appsecret);
		if(!empty($returns['errcode'])){
			//此时应该写日志，暂未写
			return false;
		}else{
			setcookie('TOKEN_KEY', $returns['access_token'], time() + 7200, '/', DOMAIN);
			// session
			\App\Libs\Cache\Memcached::set(self::$prefix . $key, $returns['access_token'], 3600);

			return $returns['access_token'];
		}
	}
	
	/**
	*	@Usage： 获取签名
	*/
	public static function getSignature( $url = ""){
		if(empty($url)){
			$url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
		}
		$token = self::token();
		$jsapi_ticket = self::getTicket();
		$noncestr = self::getGenerate(16);//16位随机数
		$time = time();
		$str = 'jsapi_ticket='.$jsapi_ticket.'&noncestr='.$noncestr.'&timestamp='.$time.'&url='.$url;		
        $signatureSha1 =  sha1("jsapi_ticket=$jsapi_ticket&noncestr=$noncestr&timestamp=$time&url=$url");
		return ['signature'=>$signatureSha1,'time'=>$time,'ticket'=>$jsapi_ticket,'noncestr'=>$noncestr,'token'=>$token,'appID'=>self::$appID];
	}
	
	/**
	*	@Usage：获取临时票据 jsapi_ticket
	*/
	public static function getTicket(){
		$key = self::generate("wx_ticket");
		$ticketMem = \App\Libs\Cache\Memcached::get(self::$prefix . $key);
		/*if(!empty($ticketMem)){
			return $ticketMem;
		}*/
		if (isset($_COOKIE['TICKET_KEY']) && ! empty($_COOKIE['TICKET_KEY'])) {
            return trim($_COOKIE['TICKET_KEY']);
        }
		$returns = self::http_get_data("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".self::token()."&type=jsapi");
		if($returns['errcode'] != 0){
			//此时应该写日志，暂未写
			return false;
		}else{
			setcookie('TICKET_KEY', $returns['ticket'], time() + 7200, '/', DOMAIN);
			// session
			\App\Libs\Cache\Memcached::set(self::$prefix . $key, $returns['ticket'], 3600);
			return $returns['ticket'];
		}
	}
	
	/**
	*	下载图片
	*	多媒体id
	*/
	public static function downMedia( $media_id ){
		$returns = self::http_get_data("http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=".self::token()."&media_id={$media_id}");
		echo "<pre>";
		print_r($returns);
		return $returns;
	}
	/**
	* 	下载图片
	*/
	public static function saveMedia( $media_id ){
		$url = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=".self::token()."&media_id={$media_id}";
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);    
        curl_setopt($ch, CURLOPT_NOBODY, 0);    //对body进行输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $package = curl_exec($ch);
        $httpinfo = curl_getinfo($ch);
       
        curl_close($ch);
        $media = array_merge(array('mediaBody' => $package), $httpinfo);
        
        //求出文件格式
        preg_match('/\w\/(\w+)/i', $media["content_type"], $extmatches);
        $fileExt = $extmatches[1];
		$sid = date("YmdHis").mt_rand(1000,9999);
		$filename = $sid.mt_rand(1000,9999).".{$fileExt}";
        $dirname = APP_PATH.'/public/uploads/';
        if(!file_exists($dirname)){
            mkdir($dirname,0777,true);
        }
		//echo $dirname.$filename;
        file_put_contents($dirname.$filename,$media['mediaBody']);
        return $filename;
    }
	/**
	*	保存微信文件
	*	$newfolder 目录
	*	$filecontent 图片内容
	*/
	public static function saveWeixinFile($newfolder, $filecontent)  
	{     
		self::createFolder($newfolder);
		$sid = date("YmdHis").mt_rand(1000, 9999);
		$filename = $sid.mt_rand(10000,9999).".jpg";
		$local_file = fopen($newfolder."/".$filename, 'w');  
		if (false !== $local_file){  
			  
			if (false !== fwrite($local_file, $filecontent)) {  
			  
				fclose($local_file);  
			 
			}  
		}  
	}  

	/**
	*	创建文件
	*/
	 private static function createFolder($path)  
	 {  
		  if (!file_exists($path))  
		  {  
			self::createFolder(dirname($path));  
			mkdir($path, 0777);  
		  }  
	 }  
		
	/**
	*	@Usage: 获取随机数
	*/
	public static function getGenerate( $length = 8 ) {
		// 密码字符集，可任意添加你需要的字符
		$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

		$password = '';
		for ( $i = 0; $i < $length; $i++ )
		{
			$password .= $chars[ mt_rand(0, strlen($chars) - 1) ];
		}

		return $password;
	}
	
	 private static function generate($uid) {
        return  md5(md5($uid . ':' . mt_rand(1, 1000)) . microtime());
    }
//数组到xml
	public static function arrayToXml($arr)
    {
        $xml = "<xml>";
        /*$xml = '<?xml version="1.0" encoding="UTF-8"?>';*/
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                 $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    //将XML转为array
    public static function xmlToArray($xml)
    {
        //禁止引用外部xml实体
        //libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
@$fp = fopen('./b.txt', 'a+');
	@fwrite($fp, PHP_EOL . 'result：'. date('Y-m-d H:i:s',time()) . '##111##' . $xml  .PHP_EOL);
@fclose($fp);
        return $values;
    }


    public static function prePay($code, $tradeId, $goodsInfo, $totalFee,$type='buy') {
    	$params = array(
    		'appid' => self::$appID,
    		'mch_id' => self::$mchID,
    		'device_info' => 'WEB',
    		'nonce_str' => self::getGenerate(mt_rand(20,32)),
    		'body' => $goodsInfo,
    	);
        //删除了.date('His')
    	$params['out_trade_no'] = $tradeId;
    	$params['total_fee'] = $totalFee;
    	$params['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'];
    	$params['time_start'] = date('YmdHis');
    	$params['time_expire'] = date('YmdHis', time() + 1800);
    	$params['notify_url'] = 'https://'.$_SERVER['HTTP_HOST'].'/notify/notifyAll';
    	$params['trade_type'] = 'APP';
    	//增加了type
    	$params['attach'] = $type;
    	ksort($params);
    	$str = urldecode(http_build_query($params));
    	$str .= '&key=' . self::$key;
    	$params['sign'] = strtoupper(md5($str));
@$fp = fopen('./b.txt', 'a+');
			@fwrite($fp, PHP_EOL . 'result：'. date('Y-m-d H:i:s',time()) . '##111##' . json_encode($params)  .PHP_EOL);
			@fwrite($fp, PHP_EOL . 'result：'. date('Y-m-d H:i:s',time()) . '##111##' . $str  .PHP_EOL);
fclose($fp);

    	//$codeInfo = self::getCodeInfo($code);
    	//$params['openid'] = $codeInfo['openid'];
	$paramsXml = self::arrayToXml($params);
    	$response = Remote::request('wx_pay', 'pay/unifiedorder', $paramsXml);
	$response['body'] = self::xmlToArray($response['body']);
@$fp = fopen('./b.txt', 'a+');
			@fwrite($fp, PHP_EOL . 'result：'. date('Y-m-d H:i:s',time()) . '##111##' . json_encode($response)  .PHP_EOL);
fclose($fp);
    	// 存储prepay
    	$prepayId = false;
    	$json = false;
    	if ($response['http_code'] == 200) {
    		$json = $response['body'];
    	}
    	

    	// add prepay log
    	/*$log = array();
    	$log['user_id'] = $uid;
    	$log['openid'] = $codeInfo['openid'];
    	$log['unionid'] = $codeInfo['unionid'];
    	$log['res_code'] = $response['http_code'];
    	$log['res'] = json_encode($response);
    	$log['req'] = json_encode($params);
    	if (!empty($json) && $json['return_code'] === 'SUCCESS' && $json['result_code'] === 'SUCCESS') {
    		$prepayId = $json['prepay_id'];
    		$log['trade_type'] = $json['trade_type'];
    		$log['prepay_id'] = $json['prepay_id'];
    		$log['code_url'] = $json['code_url'];
    	}
    	$log['ctime'] = date('Y-m-d H:i:s');
    	Pdo::insert('t_yub_pay', $log);*/
	if (!empty($json) && $json['return_code'] === 'SUCCESS' && $json['result_code'] === 'SUCCESS') {
                 $prepayId = $json['prepay_id'];
	}

@$fp = fopen('./b.txt', 'a+');
			@fwrite($fp, PHP_EOL . 'json：'. date('Y-m-d H:i:s',time()) . '##111##' . $prepayId  .PHP_EOL);
fclose($fp);
    	return $prepayId;
    }

    function getCodeInfo($code) {
    	//https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

    	$params = array(
    		'appid' => self::$appID,
    		'secret' => self::$secret,
    		'code' => $code,
    		'grant_type' => 'authorization_code',
    	);
    	$uri = 'sns/oauth2/access_token';

    	$response = Remote::request('wx_sns', $uri, $params);
    	if ($response['http_code'] != '200') {
    		return false;
    	}
    	$json = json_decode($response['body'], true);

    	// TODO 存储 appid union id
    	return $json;
    }
	
	//验证回调参数,微信app支付
	public static function validate($params){
		$origin_sign = $params['sign'];
		unset($params['sign']);
    	$sign = self::getSignature($params);

		if($origin_sign === $sign && $params['return_code'] == 'SUCCESS'){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	*	Usage:	curl 		  		  CURL请求
	*	@param  string $url 		  请求的url
	*	@param  array  $data   请求所携带的数据
	*	@param  array  $params		  其他参数
	*			参数	method		  请求方法：POST PUT 
	*			参数	header		  请求头
	*	@return array
	*/
	private static function http_curl_data($url, $data,$params = []) {  
		$params = array_merge(['method'=>'POST','header'=>['application/x-www-form-urlencoded;charset=utf-8']],$params);
		//print_r($params);
        $ch = curl_init();    
        curl_setopt($ch, CURLOPT_POST, 1);  
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $params['method']);		
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);  
        curl_setopt($ch, CURLOPT_HTTPHEADER, $params['header']);
		//curl_exec ( $ch );
		//echo curl_error( $ch );
		//die;
		//开启缓冲，获取数据
	    ob_start ();
		
		curl_exec ( $ch );
		$result = ob_get_contents ();
		ob_end_clean ();
		//返回
        return json_decode($result,true);  
    } 
	
	/**
	*	Usage:				curl_get请求
	*	$param string $url  请求的url
	*	@return array
	*/
	public static function http_get_data($url){
		$curl = curl_init();
		//设置抓取的url
		curl_setopt($curl, CURLOPT_URL, $url);
		//设置头文件的信息作为数据流输出m
		//curl_setopt($curl, CURLOPT_HEADER, 1);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);  
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); 
		//设置获取的信息以文件流的形式返回，而不是直接输出。
		//curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		//curl_setopt($curl, CURLOPT_HTTPHEADER, ["Authorization:Bearer ".self::token()]);
		ob_start ();
		curl_exec ( $curl );
		$result = ob_get_contents ();
		ob_end_clean ();
		//关闭URL请求
		curl_close($curl);
		return json_decode($result,true);
	}
}
